{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 数据"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 导入 TensorFlow\n",
    "import tensorflow as tf\n",
    "# 即显模式\n",
    "tf.enable_eager_execution()\n",
    "import numpy as np"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 生成数据\n",
    "def taxi(x):\n",
    "    init = 14.\n",
    "    unit = 2.5\n",
    "    if x<3:\n",
    "        return tf.constant(init)\n",
    "    else:\n",
    "        return init + unit*(x-3)\n",
    "    \n",
    "n_example = 100\n",
    "X = tf.random_uniform([n_example], 0, 6)\n",
    "Y = np.array([taxi(x) for x in X])\n",
    "\n",
    "# 训练集\n",
    "train_x = X[:80].numpy().reshape(-1,1)\n",
    "train_y = Y[:80].reshape(-1,1)\n",
    "\n",
    "# 测试集\n",
    "test_x = X[80:].numpy().reshape(-1,1)\n",
    "test_y = Y[80:].reshape(-1,1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<matplotlib.legend.Legend at 0x7feab839a128>"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# 显示训练集\n",
    "import matplotlib.pyplot as plt\n",
    "#plt.plot(train_x, train_y, color='green')\n",
    "plt.scatter(train_x, train_y)\n",
    "plt.legend(['Rule','Data'])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 模型"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "import tensorflow.contrib.eager as tfe\n",
    "# 定义模型\n",
    "# 初始化方法\n",
    "def inits(shape):\n",
    "    return tf.random_uniform(shape,\n",
    "            minval=-np.sqrt(5) * np.sqrt(1.0 / shape[0]),\n",
    "            maxval=np.sqrt(5) * np.sqrt(1.0 / shape[0]))\n",
    "class Model(object):\n",
    "    def __init__(self):\n",
    "        ######  参数   #####\n",
    "        \n",
    "        \n",
    "        \n",
    "        ####################\n",
    "    \n",
    "    def __call__(self, x):\n",
    "        ####  正向传递  ####\n",
    "        \n",
    "        \n",
    "        \n",
    "        ####################\n",
    "        return y\n",
    "# 实例模型\n",
    "model = Model()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 训练"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 误差\n",
    "def loss(prediction, label):\n",
    "    loss = tf.reduce_mean(tf.square(prediction - label))\n",
    "    return loss\n",
    "\n",
    "# 反向传递\n",
    "def train(model, x, y, learning_rate, batch_size, epoch):\n",
    "    # 次数\n",
    "    for e in range(epoch):\n",
    "        # 批量\n",
    "        for b in range(0,len(x),batch_size):\n",
    "            ####  梯度计算  ####\n",
    "        \n",
    "        \n",
    "        \n",
    "            ####################\n",
    "            ####  参数更新  ####\n",
    "        \n",
    "        \n",
    "        \n",
    "            ####################\n",
    "        ######   显示   #####\n",
    "        \n",
    "        \n",
    "        \n",
    "        ####################\n",
    "\n",
    "######   训练   #####\n",
    "\n",
    "\n",
    "\n",
    "####################\n",
    "\n",
    "# 评估\n",
    "test_p = model(test_x)\n",
    "print(\"Final Test Loss: %s\" %loss(test_p, test_y).numpy())\n",
    "\n",
    "# 可视化\n",
    "plt.scatter(test_x,test_y)\n",
    "plt.scatter(test_x,test_p)\n",
    "plt.legend(['real','predicted'])\n",
    "\n",
    "\n",
    "# 预测\n",
    "test_p = model(np.array([1.,4.,10.,15.,]).reshape(-1,1).astype('float32'))\n",
    "print(test_p.numpy())"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 1
}
